extern crate core;

use std::fmt::{Display, Formatter};

use cli::Arguments;
use config::ConfigError;
use glob::PatternError;

use crate::tiling::tiles::tile_list::TileList;
use crate::tiling::{MissingTilePolicy, SlotGrid, TileSelectionPolicy, VacancyPolicy};
use crate::tiling::tiles::TileType;

pub mod cli;
mod configuration;
mod tiling;

#[cfg(test)]
mod tests;

pub fn run(args: Arguments) -> Result<(), Error> {
    let _ = configuration::load(args.config, None);
    let _ = SlotGrid::new(
        args.rows as usize,
        args.cols as usize,
        TileList {
            tiles: vec![],
            horizontal_connector_names: vec![],
            vertical_connector_names: vec![],
            tile_type: TileType::Svg,
        },
        None,
        MissingTilePolicy::Avoid,
        TileSelectionPolicy::Priority,
        VacancyPolicy::Avoid,
    )?;
    Ok(())
}

#[cfg_attr(test, derive(Debug, PartialEq))]
pub enum Error {
    IoError(String),
    ValueError(String),
    TileNotFoundException(String),
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let message = match self {
            Error::IoError(msg) => msg,
            Error::ValueError(msg) => msg,
            _ => panic!(),
        };
        write!(f, "{}", message)
    }
}

impl From<ConfigError> for Error {
    fn from(error: ConfigError) -> Self {
        Error::ValueError(error.to_string())
    }
}

impl From<PatternError> for Error {
    fn from(error: PatternError) -> Self {
        Error::ValueError(error.to_string())
    }
}
